﻿using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;
using OrganizedConfusion.Game_Objects;
using System.Collections.Generic;

namespace OrganizedConfusion
{
    public class GamePlay : GameState
    {
        // TODO (GIBBS): Make an int to store the index for the texture


        ///////////////////////////////////////////////////////////////
        int testImg, bg;
        SpriteBatch Spritebatch;
        CameraManager CamManager;
        List<Player> Players;
        List<BaseObject> RenderList;
        ObjectManager OM = ObjectManager.GetInstance();
        ContentsManager CM = ContentsManager.Instance;
        PlayerIndex controlling = PlayerIndex.One;
        int tempXVel = 0;

        public GamePlay() { }

        public override void LoadContent()
        {
            base.LoadContent();
            Players = new List<Player>();
            RenderList = new List<BaseObject>();

            Inputmanager.AcquireGamePad(GamePad.GetState(0));
            Inputmanager.AcquireKeyboard(Keyboard.GetState());


            // TODO (GIBBS): Do CM.LoadTexture() and pass in the texture you want to load.
            // It returns an int with the index of where the texture is stored.


            ///////////////////////////////////////////////////////////////

            testImg = CM.LoadTexture("Textures/1280x720");
            bg = CM.LoadTexture("Textures/background");

            CamManager = new CameraManager(Statemanager.GraphicsDevice.Viewport);

            Players = OM.GetPlayers();

            for (int i = 0; i < Players.Count; i++)
            {
                Players[i].SetGame(this);
                CamManager.AddCamera();
            }

            CamManager.IsHorizontal = true;
        }

        public override void Update(GameTime gameTime)
        {
            Input();

            for (int i = 0; i < CamManager.Number_Of_Cameras; i++)
            {
                RenderList = OM.MakeDrawingList(CamManager.GetCamera(i));

                Players[i].Update(gameTime);
                CamManager.GetCamera(i).Update(Players[i]);

                OM.CheckCollision(RenderList, Players[i]);
            }
        }

        public override void Render(GameTime gameTime)
        {
            Spritebatch = Statemanager.Spritebatch;

            Statemanager.GraphicsDevice.Viewport = CamManager.GetDeafultPort;
            Statemanager.GraphicsDevice.Clear(Color.CornflowerBlue);


            for (int i = 0; i < CamManager.Number_Of_Cameras; i++)
            {
                Statemanager.GraphicsDevice.Viewport = CamManager.GetViewPort(i);
                Spritebatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, CamManager.GetCamera(i).GetViewMatrix(Vector2.One));
                Spritebatch.Draw(CM.Draw(bg), new Vector2(0, 0), Color.White);
                Spritebatch.Draw(CM.Draw(bg), new Vector2(512, 0), Color.White);
                Spritebatch.Draw(CM.Draw(bg), new Vector2(768, 0), Color.White);
                Spritebatch.Draw(CM.Draw(testImg), new Vector2(0, 500), Color.White);

                // Get all the objects to render that are on screen.
                RenderList = OM.MakeDrawingList(CamManager.GetCamera(i));
                // Render those objects
                OM.RenderObjects(RenderList, Spritebatch);

                // Loop through other players, change their color, put a tag on top
                for (int j = 0; j < Players.Count; j++)
                {
                    if (j < Players.Count && i != j)
                    {
                        Spritebatch.DrawString(Statemanager.Font, "Player " + (j + 1).ToString(), new Vector2(Players[j].Position.X - Players[j].ImageDimensions.X, Players[j].Position.Y - Players[j].ImageDimensions.Y), Color.Red);
                        Spritebatch.Draw(CM.Draw(Players[j].Image), Players[j].Position, null, Color.LightGoldenrodYellow, Players[j].Rotation, Players[j].Origin, Players[j].Scale, SpriteEffects.None, 0.0f);
                    }
                }
                Spritebatch.Draw(CM.Draw(Players[i].Image), Players[i].Position, null, Color.White, Players[i].Rotation, Players[i].Origin, Players[i].Scale, SpriteEffects.None, 0.0f);

                Spritebatch.DrawString(Statemanager.Font, "Viewport #" + i.ToString(), new Vector2(CamManager.GetViewPort(i).Width * .5f, CamManager.GetViewPort(i).Height * .5f), Color.Black);
                Spritebatch.DrawString(Statemanager.Font, "PortID #" + CamManager.GetCamera(i).PortID.ToString(), new Vector2(CamManager.GetViewPort(i).Width * .5f, CamManager.GetViewPort(i).Height * .55f), Color.Black);
                Spritebatch.End();
            }

            // GUI stuff goes here. MUST BE DONE between the Begin() and End() calls.
            Statemanager.GraphicsDevice.Viewport = CamManager.GetDeafultPort;
            Spritebatch.Begin();


            // TODO (GIBBS): Do Spritebatch.Draw() for Textures and Spritebatch.DrawString() for text.
            // Draw() param1: Do CM.Draw() and pass in the index of the texture.
            // Draw() param2: The position, easier if done with a Vector2
            // Draw() param3: Do Color.White to draw the original color, otherwise do Color.____(for color mask)
            // DrawString() param1: Do Statemanager.Font to get the SpriteFont (This IS a texture font)
            // DrawString() param2: The string to draw
            // DrawString() param3: The position to draw it, best done as a Vector2
            // DrawString() param4: The color to draw the text


            ///////////////////////////////////////////////////////////////


            Spritebatch.DrawString(Statemanager.Font, Players[0].Position.ToString(), new Vector2(50, 300), Color.DarkRed);
            Spritebatch.DrawString(Statemanager.Font, gameTime.ElapsedGameTime.Milliseconds.ToString(), new Vector2(50, 320), Color.DarkRed);
            Spritebatch.End();
        }

        public override void Input()
        {
            // DO NOT CHANGE THIS IF CHECK
            if (Inputmanager.KeyPressedBuffered(Keys.Escape) || Inputmanager.ButtonPressedBuffered(Buttons.Back))
            {
                CamManager.RemoveAll();
                Statemanager.EndGame();
            }

            if (Inputmanager.KeyPressedBuffered(Keys.Q))
                Players[0].LoadImage("Textures/DeN_Block");

            if (Inputmanager.KeyPressedBuffered(Keys.Right) || Inputmanager.LeftStickX_Buffered(PlayerIndex.One))
                Players[0].Velocity += new Vector2(50, 0);

            //if (Inputmanager.LeftStickPressure(controlling).X > 0.5f)
            //{
            //    tempXVel++;
            //    Players[0].Velocity += new Vector2(tempXVel, 0);
            //}

            if (Inputmanager.KeyPressedBuffered(Keys.Up) || Inputmanager.LeftStickY_Buffered(PlayerIndex.One, 1))
            {
                if (Players[0].Velocity.Y == 0.0f)
                    Players[0].Velocity += new Vector2(0, -500);
            }
            if (Inputmanager.KeyPressedBuffered(Keys.Left) || Inputmanager.LeftStickX_Buffered(PlayerIndex.One))
                Players[0].Velocity += new Vector2(-50, 0);
            if (Inputmanager.KeyPressedBuffered(Keys.Down) || Inputmanager.LeftStickY_Buffered(PlayerIndex.One, -1))
                Players[0].Velocity += new Vector2(0, 50);


            //if (Inputmanager.LeftStickPressure(controlling).X < -0.5f)
            //{
            //    tempXVel--;
            //    Players[0].Velocity += new Vector2(tempXVel, 0);
            //}
            //if (Inputmanager.LeftStickPressure(controlling).X < -0.5f) 
            //    Players[0].Velocity += new Vector2(0, 50);



            if (Inputmanager.KeyPressedBuffered(Keys.P) || Inputmanager.ButtonPressedBuffered(Buttons.Y))
            {
                if (Players[0].MyCheckpoint == null)
                    Players[0].Position = Players[0].StartPos;//new Vector2(340, 350);
                else
                    Players[0].Position = Players[0].MyCheckpoint.Position;
            }

            if (Inputmanager.KeyPressedBuffered(Keys.M))
                Players[0].ChangeScale(1.0f);

            if (Inputmanager.KeyPressedBuffered(Keys.O))
                Players[0].ChangeScale(.5f);
        }

        public void Reset()
        {
            // Reset the player's position and any bools that were turned on. Reset the state of any objects that move
            // besides the checkpoint.
            //Players[0].Position = Players[0].StartPos;
            Players[0].Velocity = new Vector2();
        }
    }
}
